package check.components;

import check.components.entity.ServiceInfo;
import check.components.util.DataUtil;
import check.components.util.HttpUtils;
import check.components.util.RedisService;
import cn.hutool.core.date.DateUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
@RequiredArgsConstructor
public class ServiceCheck {

    private final RedisService redisService;


    // 每 10 秒执行一次
    @Scheduled(cron = "*/2 * * * * *")
    public void check() {
        DataUtil.getServices().forEach(serviceInfo -> {
            boolean processRunningOnPort = isProcessRunningOnPort(serviceInfo);
            String key1 = serviceInfo.getServicePort() + "_key1";
            String key2 = serviceInfo.getServicePort() + "_key2";

            if (!processRunningOnPort) {
                if(null == redisService.get(key1)){
                    sendMsg("title="+serviceInfo.getServiceName()+"服务"+serviceInfo.getServicePort()+"停止运行");
                    redisService.delete(key2);
                }

                //重启服务
                startJarWithNohup(serviceInfo);
                redisService.set(key1, DateUtil.now());
            } else {
                if (null == redisService.get(key2)) {
                    sendMsg("title="+serviceInfo.getServiceName()+"服务"+serviceInfo.getServicePort()+"启动成功");
                    redisService.delete(key1);
                    redisService.set(key2, DateUtil.now());
                }
            }
        });
    }


    /**
     * 监测端口是否有进程占用
     *
     * @param
     * @return
     */
    public boolean isProcessRunningOnPort(ServiceInfo serviceInfo) {
        int port = serviceInfo.getServicePort();
        try {
            // 使用lsof命令检查端口占用情况
            Process process = Runtime.getRuntime().exec(new String[]{"sh", "-c", "lsof -i :" + port + " | grep LISTEN"});

            try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
                String line = reader.readLine();
                if (line != null && !line.trim().isEmpty()) {
                    // 提取进程信息
                    String[] parts = line.split("\\s+");
                    if (parts.length > 1) {
                        String pid = parts[1];
                        return true;
                    }
                }
                return false;
            }
        } catch (IOException e) {
            log.error("检查端口【{}】进程时发生错误", port, e);
            return false;
        }
    }


    public void startJarWithNohup(ServiceInfo serviceInfo) {

        //防止重复执行启动命令（例如10s反复执行该方法，会造成内存溢出）
        String key = serviceInfo.getServicePort() + "_expire";
        if (redisService.get(key) != null) {
            return;
        }

        try {
            sendMsg("title=启动"+serviceInfo.getServiceName()+"服务"+serviceInfo.getServicePort());
            // 构建完整的 nohup 命令
            String command = serviceInfo.getScriptPath();
            log.info("执行命令：{}", command);
            // 执行命令
            Process process = Runtime.getRuntime().exec(new String[]{"sh", "-c", command});
            redisService.set(key, DateUtil.now(), serviceInfo.getStartMinute(), TimeUnit.MINUTES);
        } catch (IOException e) {
            log.error("启动Jar时发生错误", e);
        }
    }


    //消息通知：采用https://xz.qqoq.net/方式
    public void sendMsg(String params) {
        String url = "https://xizhi.qqoq.net/XZec7eea2083e39d8d23b4d543b573ba5c.send?";
        String s = HttpUtils.sendPost(url, params);
    }
}
